//------------------------------------------------------------------------------
// <copyright file="InputBindingsProperties.cs" company="Damian Antonowicz">
//       copyright © 2010 Damian Antonowicz
// </copyright>
// <author>Damian Antonowicz</author>
// <email>poczta@damianantonowicz.pl</email>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using DotBeer.Data.Properties;
using System.Windows.Input;
using DotBeer.UI.WPFClient.ViewModels;
using DotBeer.Business.Entities;
using DAnton.Utilities.Helpers.KeyBindings;
using System.Diagnostics;
using System.Reflection;

namespace DotBeer.UI.WPFClient
{
    public class InputBindingsProperties
    {
        #region private members

        Window window;

        #endregion

        #region properties

        private string WindowBindingKey
        {
            get { return String.Format("{0}Binding", this.window.GetType().Name); }
        }

        private string GlobalBindingKey
        {
            get { return "GlobalBinding"; }
        }

        public static readonly DependencyProperty UseInputBindingsProperty =
            DependencyProperty.RegisterAttached("UseInputBindings",
                                                typeof(bool),
                                                typeof(InputBindingsProperties),
                                                new PropertyMetadata(UseInputBindingsProperty_Changed));

        #endregion

        #region constructors

        public InputBindingsProperties(Window window)
        {
            this.window = window;
            this.window.Loaded += new RoutedEventHandler(window_Loaded);

            WindowsBindingsSettings.Default.SettingsSaving += new System.Configuration.SettingsSavingEventHandler(WindowsBindingsSettings_SettingsSaving);
        }

        #endregion

        #region public methods

        public static void SetUseInputBindingsProperty(DependencyObject d, bool use)
        {
            d.SetValue(UseInputBindingsProperty, use);
        }

        public static bool GetUseInputBindingsProperty(DependencyObject d)
        {
            return (bool)d.GetValue(UseInputBindingsProperty);
        }

        #endregion

        #region private methods

        private static void UseInputBindingsProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window window = d as Window;

            if (window != null)
            {
                if ((bool)e.NewValue)
                {
                    InputBindingsProperties bindingsProp = new InputBindingsProperties(window);
                }
            }
        }

        private void WindowsBindingsSettings_SettingsSaving(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.SetInputKeyBindings();
        }

        private void window_Loaded(object sender, RoutedEventArgs e)
        {
            this.SetInputKeyBindings();
        }

        private void SetInputKeyBindings()
        {
            this.window.InputBindings.Clear();

            if (this.window.DataContext != null)
            {
                Type viewModelType = this.window.DataContext.GetType();
                List<PropertyInfo> viewModelProperties = new List<PropertyInfo>(viewModelType.GetProperties());

                Type bindingsSettingsType = WindowsBindingsSettings.Default.GetType();
                PropertyInfo[] bindingsSettingsProperties = bindingsSettingsType.GetProperties();

                foreach (PropertyInfo property in bindingsSettingsProperties)
                {
                    string commandName = "";

                    if (property.Name.StartsWith(this.WindowBindingKey))
                    {
                        commandName = property.Name.Substring(this.WindowBindingKey.Length);
                    }
                    else if (property.Name.StartsWith(this.GlobalBindingKey))
                    {
                        commandName = property.Name.Substring(this.GlobalBindingKey.Length);
                    }

                    if (commandName != "")
                    {
                        PropertyInfo viewModelProp = viewModelProperties.SingleOrDefault(p => p.Name == commandName);

                        if (viewModelProp != null)
                        {
                            SerializableKeyGesture gesture = property.GetValue(WindowsBindingsSettings.Default, null) as SerializableKeyGesture;
                            ICommand command = viewModelProp.GetValue(this.window.DataContext, null) as ICommand;

                            InputBinding binding = new InputBinding(command, gesture);
                            this.window.InputBindings.Add(binding);
                        }
                    }
                }
            }
        }

        #endregion
    }
}
